<template>
  <div id="tableSearch">
    <el-card class="search" shadow="hover">
      <div slot="header" class="card-title flex-a-center">
        <i class="el-icon el-icon-search" />
        筛选查询
        <div class="operate">
          <el-button @click="onSearchSubmit" type="primary" size="medium" native-type="submit">查询</el-button>
          <el-button @click="onSearchReset" type="default" size="medium" native-type="reset">重置</el-button>
        </div>
      </div>
      <slot name="table-search"></slot>
      <el-form
        inline
        label-width="8em"
        size="medium"
        style="margin-bottom: -22px"
      >
        <!-- <el-row> -->
          <!-- <el-col
            v-for="item in searchColumns"
            :span="item.span"
            :key="item.key"
          > -->
            <el-form-item
              v-for="item in searchColumns"
              :key="item.key"
              :label="`${item.title}：`"
            >
              <component
                v-if="item.component"
                :is="item.component.is"
                v-bind="item.component.props || {}"
                v-model="searchModelData[item.key]"
              />
              <el-date-picker
                v-else-if="item.type === 'time'"
                v-model="searchModelData[item.key]"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="yyyy-MM-dd HH:mm:ss"
                format="yyyy-MM-dd HH:mm:ss"
              >
              </el-date-picker>
              <el-select
                v-else-if="item.type === 'select'"
                :value="searchModelData[item.key] || ''"
                @input="$set(searchModelData, item.key, $event)"
                :placeholder="`请选择${item.title}`"
              >
                <el-option
                  v-for="option in item.options"
                  :key="option.value || 'all'"
                  :value="option.value"
                  :label="option.label"
                ></el-option>
              </el-select>
              <el-input
                v-else
                v-model="searchModelData[item.key]"
                :placeholder="`请输入${item.title}`"
              ></el-input>
            </el-form-item>
          <!-- </el-col>
        </el-row> -->

      </el-form>
    </el-card>
    <br />
    <!-- <template v-if="tabsOptions">
      <div class="tabs">
        <el-button
          v-for="item in tabsOptions.list"
          :key="item.code"
          :type="tabState.currentCode === item.code ? 'primary' : 'default'"
          @click="onSwitchTab(item)"
        >{{item.desc}}(<span class="number">{{tabsOptions.data[item.code]}}</span>)</el-button>
      </div>
      <br />
    </template> -->
    <el-card
      class="table"
      shadow="hover"
      body-style="padding: 0"
    >
      <div slot="header" class="card-title flex-a-center">
        <i class="el-icon el-icon-notebook-2" />
        {{title}}
        <slot name="table-title"></slot>
      </div>
      <el-table
        ref="table"
        v-loading="tableState.loading"
        :data="tableState.data"
        stripe
        style="width: 100%"
        @selection-change="onSelectionChange"
      >
        <!-- header-cell-style="background-color: #f5f5f5;color: #333;font-weight: bold;text-align:center" -->
        <el-table-column v-if="selection" align="center" type="selection" width="50"></el-table-column>
        <el-table-column
          v-for="item in tableColumns"
          :key="item.dataIndex"
          :prop="item.dataIndex"
          :label="item.title"
          :align="item.align || 'center'"
          :width="item.width || null"
        >
          <template slot-scope="scope">
            <slot :name="item.dataIndex" v-bind="scope">{{(item.formatter ? item.formatter(scope.row[item.dataIndex], scope.row) : scope.row[item.dataIndex]) || '-'}}</slot>
          </template>
        </el-table-column>

      </el-table>
      <div class="pagination">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next, jumper"
          :current-page="tableState.pageIndex"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="tableState.pageSize"
          :total="tableState.total"
          @size-change="onPageSizeChange"
          @current-change="onPageIndexChange"
        >
        </el-pagination>
      </div>
    </el-card>
  </div>
</template>

<script>
import Http from '@/lib/http';
import { formatObjectEmpty } from '@/lib/util';
export default {
  props: {
    columns: Array,
    api: {
      type: Function,
      default: () => ({ list: [], total: 0 }),
    },
    title: String,
    selection: Boolean,
    exportApi: [String, Function],
    tableProps: Object,
  },
  data () {
    return {
      tableState: {
        pageIndex: 1,
        pageSize: 10,
        loading: false,
        data: [],
        total: 0,
      },
      searchParams: {},
      searchModelData: {},
      selectionItems: [],
    };
  },
  computed: {
    searchColumns () {
      const { columns, searchModelData, $route, searchParams } = this;
      const searchColumns = [];
      columns.forEach((column) => {
        if (column.search) {
          const search = typeof column.search === 'object' ? column.search : {};
          search.key = search.key ? search.key.toString() : column.dataIndex;
          search.column = column;
          search.type = this.getSearchType(search);
          search.title = search.title || column.title;
          search.span = search.span || 8;
          searchColumns.push(search);
          if ($route.query[search.key] && !searchModelData[search.key]) {
            searchModelData[search.key] = searchParams[search.key] = $route.query[search.key].trim();
          }
        }
      });
      return searchColumns.sort((a, b) => (a.sort || 1) - (b.sort || 1));
    },
    tableColumns () {
      return this.columns.filter((column) => !column.hide);
    },
  },
  mounted () {
    this.getList();
  },
  watch: {
    '$route' () {
      this.onSearchSubmit();
    },
  },
  methods: {
    getSearchType (search) {
      const { column, type } = search;
      if (type) {
        return type;
      } else if (/time/i.test(column.dataIndex)) {
        return 'time';
      }
    },
    initSearchParams () {
      const { searchModelData, searchParams } = this;
      Object.keys(searchModelData).forEach((key) => {
        const value = searchModelData[key];
        if (key.indexOf(',') > -1) {
          key.split(',').forEach((key, index) => {
            searchParams[key] = Array.isArray(value) && value[index] ? value[index] : null;
          });
        } else {
          searchParams[key] = value;
        }
      });
    },

    getSearchParams () {
      const searchParams = this.searchParams;
      const query = {};
      Object.keys(searchParams).forEach(key => {
        if (searchParams[key] === null || searchParams[key] !== '') {
          query[key] = searchParams[key];
        }
      });
      return query;
    },

    async getList () {
      const { tableState } = this;
      tableState.loading = true;
      try {
        const { list, total } = await this.api(
          tableState.pageIndex,
          tableState.pageSize,
          this.getSearchParams(),
        );
        tableState.data = list;
        tableState.total = total;
      } catch (error) {

      } finally {
        tableState.loading = false;
      }
    },
    onSearchReset () {
      const { searchModelData } = this;
      Object.keys(searchModelData).forEach((key) => {
        searchModelData[key] = Array.isArray(searchModelData[key]) ? [] : '';
      });
    },
    onSearchSubmit () {
      this.initSearchParams();
      this.tableState.pageIndex = 1;
      this.getList();
    },

    onPageSizeChange (val) {
      this.tableState.pageSize = val;
      this.tableState.pageIndex = 1;
      this.getList();
    },

    onPageIndexChange (val) {
      this.tableState.pageIndex = val;
      this.getList();
    },

    onSelectionChange (val) {
      this.selectionItems = val;
      this.$emit('selection-change', val);
    },

    reload (pageIndex) {
      this.getList();
    },

    onExport () {
      if (typeof this.exportApi === 'function') {
        this.exportApi(this.getSearchParams());
      } else {
        window.open(Http.getUrl(this.exportApi, formatObjectEmpty(this.getSearchParams())));
      }
    },

    showLoading () {
      this.tableState.loading = true;
    },

    hideLoading () {
      this.tableState.loading = false;
    },

    clearSelection () {
      this.$refs.table.clearSelection();
    },
  },
};
</script>

<style lang="scss">
#tableSearch {
  .el-card__header {
    // background-color: #f5f5f5;
  }
  .card-title {
    .el-icon {
      margin-right: 5px;
      font-size: 1.2em;
    }
    .operate {
      flex: 1;
      text-align: right;
    }
  }
  .search .el-card__header{
    padding: 10px 20px;
  }
  .tabs .el-button--default .number {
    color: red;
  }

  .pagination {
    text-align: right;
    padding: 12px;
  }
}
</style>
